package com.pengiummer.blogpublisher.editors;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.List;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.registry.EditorRegistry;
import org.eclipse.ui.part.FileEditorInput;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.pengiummer.blogpublisher.popup.actions.BlogClient;
import com.pengiummer.blogpublisher.popup.actions.Post;
import com.pengiummer.blogpublisher.utils.XMLUtils;

public class InteractiveControlPage {
	private final static String DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss";
	private Text blogNameTxt;
	private Text pwdTxt;
	private Text userNameTxt;
	private Table blogTable;
	private final EditorRegistry registry = (EditorRegistry) PlatformUI.getWorkbench().getEditorRegistry();
	private IProject project;

	XPath xPath;
	Document document;
	MultiPageEditor editor;

	public InteractiveControlPage(Composite container, MultiPageEditor editor) {
		this.editor = editor;
		IFile mgrfile = (IFile) editor.getEditorInput().getAdapter(IFile.class);
		project = mgrfile.getProject();
		container.setLayout(new GridLayout(1, false));
		Composite headComposite = new Composite(container, SWT.NONE);
		headComposite.setLayout(new GridLayout(2, false));
		createUserInputs(headComposite);

		createBlogControlBtns(headComposite);

		createBlogList(container);
	}

	private void createUserInputs(Composite headComposite) {
		Composite leftComposite = new Composite(headComposite, SWT.NONE);
		leftComposite.setLayout(new GridLayout(2, false));
		Label userNameLabel = new Label(leftComposite, SWT.NONE);
		userNameLabel.setText("User Name");
		userNameTxt = new Text(leftComposite, SWT.NONE);
		Label pwdLabel = new Label(leftComposite, SWT.NONE);
		pwdLabel.setText("Password");
		pwdTxt = new Text(leftComposite, SWT.NONE);
		pwdTxt.setEchoChar('*');
		Label blogLabel = new Label(leftComposite, SWT.NONE);
		blogLabel.setText("Blog Name");
		blogNameTxt = new Text(leftComposite, SWT.NONE);
	}

	private void createBlogControlBtns(final Composite headComposite) {
		Composite rightComposite = new Composite(headComposite, SWT.NONE);
		rightComposite.setLayout(new GridLayout(1, false));
		Button importBtn = new Button(rightComposite, SWT.PUSH);
		importBtn.setText("Import Posts");
		importBtn.addListener(SWT.Selection, new Listener() {
			@Override
			public void handleEvent(Event event) {
				BlogClient client = new BlogClient(blogNameTxt.getText());

				try {
					client.authenticate(userNameTxt.getText(), pwdTxt.getText());
					client.initConnection();
					System.out.println(client.getBlogId());
					List<Post> posts = client.getAllPosts();
					XMLUtils.removeChildNodes(XMLUtils.getNodeByPath(document
							.getDocumentElement(), "Security", true));
					Node userNameNode = XMLUtils.getNodeByPath(document
							.getDocumentElement(), "Security/UserName", true);
					userNameNode.appendChild(document.createTextNode(userNameTxt
							.getText()));
					Node passwordNode = XMLUtils.getNodeByPath(document
							.getDocumentElement(), "Security/Password", true);
					passwordNode.appendChild(document.createTextNode(pwdTxt.getText()));
					Node blogNameNode = XMLUtils.getNodeByPath(document
							.getDocumentElement(), "Security/BlogName", true);
					blogNameNode.appendChild(document.createTextNode(blogNameTxt
							.getText()));

					Node postsNode = XMLUtils.getNodeByPath(
							document.getDocumentElement(), "Posts", true);
					XMLUtils.removeChildNodes(postsNode);
					for (Post post : posts) {
						Node postNode = document.createElement("Post");

						Node titleNode = XMLUtils.getNodeByPath(postNode, "Title", true);
						titleNode.appendChild(document.createTextNode(post.getTitle()));
						postNode.appendChild(titleNode);

						String postId = post.getId().split("post-")[1];
						Node idNode = XMLUtils.getNodeByPath(postNode, "Id", true);
						idNode.appendChild(document.createTextNode(postId));
						postNode.appendChild(idNode);

						String fileName = postId + ".txt";
						Node fileNameNode = XMLUtils.getNodeByPath(postNode, "FileName",
								true);
						fileNameNode.appendChild(document.createTextNode(fileName));
						postNode.appendChild(fileNameNode);

						IFile postFile = project.getFile(new Path(fileName));
						InputStream is = new ByteArrayInputStream(post.getHtmlContent()
								.getBytes());
						if (postFile.exists()) {
							postFile.setContents(is, true, true, new NullProgressMonitor());
						} else {
							postFile.create(is, true, new NullProgressMonitor());
						}

						String pubDate = new SimpleDateFormat(DATE_FORMAT).format(post
								.getPublishDate());
						Node pubDateNode = XMLUtils
								.getNodeByPath(postNode, "PubDate", true);
						pubDateNode.appendChild(document.createTextNode(pubDate));
						postNode.appendChild(pubDateNode);

						postsNode.appendChild(postNode);
					}
					String docContent = XMLUtils.saveDocumentToString(document);
					editor.getEditor().getDocumentProvider().getDocument(
							editor.getEditorInput()).set(docContent);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		Button newBtn = new Button(rightComposite, SWT.NONE);
		newBtn.setText("Create Post");
		newBtn.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
			}
		});
	}

	private void createBlogList(Composite topComposite) {
		Composite botComposite = new Composite(topComposite, SWT.NONE);
		botComposite.setLayout(new GridLayout(1, false));
		blogTable = new Table(botComposite, SWT.MULTI | SWT.FULL_SELECTION);
		Menu menu = new Menu(topComposite.getShell());
		MenuItem publishMenuItem = new MenuItem(menu, SWT.DROP_DOWN);
		publishMenuItem.setText("Publish");
		publishMenuItem.addSelectionListener(new SelectionAdapter(){

			@Override
			public void widgetSelected(SelectionEvent e) {
				System.out.println(e);
			}});
		blogTable.setMenu(menu );
		blogTable.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDoubleClick(MouseEvent e) {
				IFile file = project.getFile(new Path(blogTable.getSelection()[0].getText(4)));
				IEditorDescriptor preferredEditor = registry.getDefaultEditor(blogTable.getSelection()[0].getText(4));
				try {
					editor.getSite().getPage().openEditor(new FileEditorInput(file), preferredEditor.getId());
				} catch (PartInitException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				System.out.println(blogTable.getSelection()[0].getText(4));
			}
		});
		TableColumn col1 = new TableColumn(blogTable, SWT.LEFT);
		col1.setText("Title");
		col1.setWidth(200);
		TableColumn col2 = new TableColumn(blogTable, SWT.LEFT);
		col2.setText("Id");
		col2.setWidth(80);
		TableColumn col3 = new TableColumn(blogTable, SWT.LEFT);
		col3.setText("Publish Date");
		col3.setWidth(80);
		TableColumn col4 = new TableColumn(blogTable, SWT.LEFT);
		col4.setText("Modify Date");
		col4.setWidth(80);
		TableColumn col5 = new TableColumn(blogTable, SWT.LEFT);
		col5.setText("File Name");
		col5.setWidth(80);
		blogTable.setItemCount(10);

		blogTable.setHeaderVisible(true);
		blogTable.setLinesVisible(true);
	}

	public void refresh() throws XPathExpressionException, SAXException,
			IOException, ParserConfigurationException {
		xPath = XPathFactory.newInstance().newXPath();
		document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
				new ByteArrayInputStream(editor.getEditor().getDocumentProvider()
						.getDocument(editor.getEditorInput()).get().getBytes()));
		Node root = document.getDocumentElement();
		Node securityNode = (Node) xPath.evaluate("Security", root,
				XPathConstants.NODE);
		if (securityNode != null) {
			this.blogNameTxt.setText(xPath.evaluate("BlogName", securityNode));
			this.userNameTxt.setText(xPath.evaluate("UserName", securityNode));
			this.pwdTxt.setText(xPath.evaluate("Password", securityNode));
		}
		NodeList posts = (NodeList) xPath.evaluate("Posts/Post", root,
				XPathConstants.NODESET);

		blogTable.removeAll();
		if (posts != null) {
			for (int i = 0; i < posts.getLength(); i++) {
				TableItem item = new TableItem(blogTable, 0);
				item.setText(new String[] { xPath.evaluate("Title", posts.item(i)),
						xPath.evaluate("Id", posts.item(i)),
						xPath.evaluate("PubDate", posts.item(i)), "",
						xPath.evaluate("FileName", posts.item(i)) });
				item.setData(posts.item(i));
			}
		}
	}
}
